﻿using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;

namespace SSCCMembership.Web.Services.Members
{
    [ErrorHandlerBehavior]
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class ContactNumbersService
    {

        [OperationContract]
        public ContactScreen LoadContactDetails(int MemberID)
        {
            ContactScreen CS = new ContactScreen();
            using (var Q = SSCCDatabase.Query("SELECT ID, FirstName, Surname, HomePhone, HomePhoneOptOut, WorkPhone, WorkPhoneOptOut, MobilePhone, MobilePhoneOptOut, Email1, Email1OptOut, Email2, Email2OptOut FROM SSCC_DAT_Member WHERE (ID = @MemberID)",
                new SqlParameter("@MemberID",SqlDbType.Int), MemberID))
            {
                var Member = Q.First();
                CS.ContactDetails = ContactType.LoadAll(Member).ToArray();
                CS.FullName = String.Format("{0} {1}", Member["FirstName"], Member["Surname"]);
            }
            return CS;
        }
        [OperationContract]
        public void UpdateContactDetail(int MemberID, int TypeID, string Value)
        {
            ContactType.UpdateContactValue(MemberID, TypeID, Value);
        }
        [OperationContract]
        public void UpdateContactOptOut(int MemberID, int TypeID, bool Value)
        {
            ContactType.UpdateContactOptOut(MemberID, TypeID, Value);
        }
    }
    public class ContactScreen
    {
        public string FullName { get; set; }
        public ContactDetail[] ContactDetails { get; set; }
    }

    public class ContactDetail
    {
        public int TypeID { get; set; }
        public int MemberID { get; set; }

        public string ContactValue { get; set; }
        public bool? OptOut { get; set; }

        public string Name { get; set; }
        public int MaxLength { get; set; }
        public string Regex { get; set; }
    }

    public class ContactType
    {
        #region Private Members
        private ContactType(int TypeID, string Name, int MaxLength, string regex, string DBName, string DBOptOutName)
        {
            this.TypeID = TypeID;
            this.Name = Name;
            this.MaxLength = MaxLength;
            this.Regex = regex;

            this.DBName = DBName;
            this.DBOptOutName = DBOptOutName;
        }
        public int TypeID { get; set; }

        public string Name { get; set; }
        public int MaxLength { get; set; }
        public string Regex { get; set; }

        public string DBName { get; set; }
        public string DBOptOutName { get; set; }

        //public ContactDetail Load(SSCC_DAT_Member M)
        //{
        //    return new ContactDetail()
        //    {
        //        TypeID = TypeID,
        //        MemberID = M.ID,
        //        Name = Name,
        //        MaxLength = MaxLength,
        //        Regex = Regex,

        //        ContactValue = LoadValue(M),
        //        OptOut = LoadOptOut(M)
        //    };
        //}

        public ContactDetail Load(SqlDataReader M)
        {
            return new ContactDetail()
            {
                TypeID = TypeID,
                MemberID = (int)M["ID"],
                Name = Name,
                MaxLength = MaxLength,
                Regex = Regex,

                ContactValue = M[DBName].ToString(),
                OptOut = M[DBOptOutName].Nullable<bool?>()
            };
        }

        #endregion

        #region Contact Types
        const string PhoneRegex = ".*";
        const string EmailRegex = ".*";



        static readonly ContactType[] CTs = new ContactType[] 
        { 
            new ContactType(0, "Home Phone", 20, PhoneRegex, "HomePhone","HomePhoneOptOut"),
            new ContactType(1, "Mobile Phone", 20, PhoneRegex, "MobilePhone","MobilePhoneOptOut"),
            new ContactType(2, "Work Phone", 20, PhoneRegex, "WorkPhone","WorkPhoneOptOut"),
            new ContactType(3, "Email Address", 500, EmailRegex, "Email1","Email1OptOut"),
            new ContactType(4, "2nd Email Address", 500, EmailRegex, "Email2","Email2OptOut")
        };
        #endregion

            //new ContactType(0, "Home Phone", 20, PhoneRegex, (M)=>M.HomePhone,(M)=>M.HomePhoneOptOut, (M,V)=>M.HomePhone = V, (M,V)=>M.HomePhoneOptOut = V),
            //new ContactType(1, "Mobile Phone", 20, PhoneRegex, (M)=>M.MobilePhone,(M)=>M.MobilePhoneOptOut, (M,V)=>M.MobilePhone = V, (M,V)=>M.MobilePhoneOptOut = V),
            //new ContactType(2, "Work Phone", 20, PhoneRegex, (M)=>M.WorkPhone,(M)=>M.WorkPhoneOptOut, (M,V)=>M.WorkPhone = V, (M,V)=>M.WorkPhoneOptOut = V),
            //new ContactType(3, "Email Address", 500, EmailRegex, (M)=>M.Email1,(M)=>M.Email1OptOut, (M,V)=>M.Email1 = V, (M,V)=>M.Email1OptOut = V),
            //new ContactType(4, "2nd Email Address", 500, EmailRegex, (M)=>M.Email2,(M)=>M.Email2OptOut, (M,V)=>M.Email2 = V, (M,V)=>M.Email2OptOut = V)

        public static IEnumerable<ContactDetail> LoadAll(SqlDataReader M)
        {
            return CTs.Select((CT) => CT.Load(M));
        }

        public static void UpdateContactValue(int MemberID, int TypeID, string Value)
        {
            var ct = CTs.First((CT) => CT.TypeID == TypeID);
            SSCCDatabase.ExecuteStatement("UPDATE SSCC_DAT_Member SET " + ct.DBName + "=@Value WHERE ID=@ID"
                , new Dictionary<SqlParameter, object>()
                {
                    {new SqlParameter("@Value", SqlDbType.VarChar), Value},
                    {new SqlParameter("@ID", SqlDbType.Int), MemberID}
                });
        }
        public static void UpdateContactOptOut(int MemberID, int TypeID, bool Value)
        {
            var ct = CTs.First((CT) => CT.TypeID == TypeID);
            SSCCDatabase.ExecuteStatement("UPDATE SSCC_DAT_Member SET " + ct.DBOptOutName + "=@Value WHERE ID=@ID"
                , new Dictionary<SqlParameter, object>()
                {
                    {new SqlParameter("@Value", SqlDbType.Bit), Value},
                    {new SqlParameter("@ID", SqlDbType.Int), MemberID}
                });
        }
    }
}
